package com.domel76.quickfilm.common;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;

import com.domel76.quickfilm.beans.CinemaBean;
import com.domel76.quickfilm.beans.FilmBean;

public class RSSParser {
	private static final String KINO_STR = "Kino:";
	private static final String GODZ_STR = "godz.";

	public List<FilmBean> parse() {
		List<FilmBean> films = new ArrayList<FilmBean>();
		try {
			String url = "http://film.wp.pl/rss.xml?id=123";
			String rssContent = (new URLLoader()).urlGet(url);
			// File file = new File("rss.xml");
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new ByteArrayInputStream(rssContent.getBytes("ISO-8859-2")));
			doc.getDocumentElement().normalize();
			NodeList nodeLst = doc.getElementsByTagName("item");
			boolean onetime = false;
			for (int s = 0; s < nodeLst.getLength(); s++) {

				Node fstNode = nodeLst.item(s);

				if (fstNode.getNodeType() == Node.ELEMENT_NODE) {

					Element fstElmnt = (Element) fstNode;

					NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("title");
					Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
					NodeList fstNm = fstNmElmnt.getChildNodes();
					String title = ((Node) fstNm.item(0)).getNodeValue();
					//System.out.println("Title : " + title);

					NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("link");
					Element lstNmElmnt = (Element) lstNmElmntLst.item(0);
					NodeList lstNm = lstNmElmnt.getChildNodes();
					String link = ((Node) lstNm.item(0)).getNodeValue();
					link = link.replaceAll(",film.html", ",film_szczegoly.html");
					//System.out.println("Link : " + link);

					NodeList descNmElmntLst = fstElmnt.getElementsByTagName("description");
					Element descNmElmnt = (Element) descNmElmntLst.item(0);
					NodeList descNm = descNmElmnt.getChildNodes();
					//System.out.println("Description : " + ((Node) descNm.item(0)).getNodeValue());
					//System.out.println();

					// Sprawdzamy czy jest wartosc Kino
					Map<String, String> filmDesc = parseDescription(((Node) descNm.item(0)).getNodeValue());
					FilmBean film = new FilmBean();
					film.shortDescription = filmDesc.get("description");
					film.linkImage = filmDesc.get("link");
					film.title = title;
					film.link = link;
					if (!onetime) {
						// Parsujemy szczegoly filmu
						Map<String, String> details = parseFilmDetails(link);
						film.all = details.get("all");
						film.country = details.get("country");
						film.description = details.get("description");
						film.genre = details.get("genre");
						film.rating = details.get("rating");
						film.release = details.get("release");
						film.runtime = details.get("runtime");
						//onetime = true;
					}
					film.cinemas = parseCinemas(((Node) descNm.item(0)).getNodeValue());
					films.add(film);
				}
			}
			return films;
		} catch (Exception e) {
			e.printStackTrace();
			return films;
		}
	}

	public Map<String, String> parseDescription(String desc) {
		Map<String, String> sMap = new HashMap<String, String>();
		try {
			int startKino = desc.indexOf(KINO_STR);
			desc = desc.substring(0, startKino);
			int startSrc = desc.indexOf("src=\"");
			int stopSrc = desc.indexOf("\"", startSrc + 5);
			if (startSrc != -1) {
				String link = desc.substring(startSrc + 5, stopSrc);
				sMap.put("link", link);
				desc = desc.substring(stopSrc);
			} else {
				sMap.put("link", "");
			}

			int startDesc = desc.indexOf("<p>");
			int stopDesc = desc.indexOf("<br", startSrc);
			if (startDesc != -1) {
				String description = desc.substring(startDesc + 3, stopDesc);
				sMap.put("description", description);
			} else {
				sMap.put("description", "");
			}

		} catch (Exception e) {
			sMap.put("description", "Nie mo\u017cna odczyta\u0107 opsiu");
			sMap.put("link", "");
		}
		return sMap;
	}

	public List<CinemaBean> parseCinemas(String desc) {
		List<CinemaBean> kina = new ArrayList<CinemaBean>();
		String tmp = desc;
		while (tmp.indexOf(KINO_STR) > -1) {
			// Znajdujemy
			int startKino = tmp.indexOf(KINO_STR) + KINO_STR.length();

			tmp = tmp.substring(startKino);

			startKino = tmp.indexOf("<b>") + 3;
			tmp = tmp.substring(startKino);
			startKino = tmp.indexOf(">") + 1;
			tmp = tmp.substring(startKino);

			int stopKino = tmp.indexOf("<");
			String kino = tmp.substring(0, stopKino);
			// Znajdujemy godziny
			int startGodz = tmp.indexOf(GODZ_STR) + GODZ_STR.length();
			tmp = tmp.substring(startGodz);
			int stopGodz = tmp.indexOf("<");
			String godziny = tmp.substring(0, stopGodz).trim();
			tmp = tmp.substring(stopGodz);

			CinemaBean cinema = new CinemaBean();
			cinema.name = kino;

			List<String> stringList = Arrays.asList(godziny.split(","));

			cinema.hours = new ArrayList<String>();
			for (String s : stringList) {
				cinema.hours.add(s.trim());
			}

			kina.add(cinema);
		}
		return kina;

	}

	public static final String unescapeHTML(String s, int f) {
		String[][] escape = { { "&lt;", "<" }, { "&gt;", ">" }, { "&amp;", "&" }, { "&quot;", "\"" }, { "&agrave;", "à" }, { "&Agrave;", "À" },
				{ "&acirc;", "â" }, { "&auml;", "ä" }, { "&Auml;", "Ä" }, { "&Acirc;", "Â" }, { "&aring;", "å" }, { "&Aring;", "Å" }, { "&aelig;", "æ" },
				{ "&AElig;", "Æ" }, { "&ccedil;", "ç" }, { "&Ccedil;", "Ç" }, { "&eacute;", "é" }, { "&Eacute;", "É" }, { "&egrave;", "è" },
				{ "&Egrave;", "È" }, { "&ecirc;", "ê" }, { "&Ecirc;", "Ê" }, { "&euml;", "ë" }, { "&Euml;", "Ë" }, { "&iuml;", "ï" }, { "&Iuml;", "Ï" },
				{ "&ocirc;", "ô" }, { "&Ocirc;", "Ô" }, { "&ouml;", "ö" }, { "&Ouml;", "Ö" }, { "&oslash;", "ø" }, { "&Oslash;", "Ø" }, { "&szlig;", "ß" },
				{ "&ugrave;", "ù" }, { "&Ugrave;", "Ù" }, { "&ucirc;", "û" }, { "&Ucirc;", "Û" }, { "&uuml;", "ü" }, { "&Uuml;", "Ü" }, { "&nbsp;", " " },
				{ "&reg;", "\u00a9" }, { "&copy;", "\u00ae" }, { "&euro;", "\u20a0" }, { "&#8221;", "\"" }, { "&#8222;", "\"" }, { "&#8230;", "..." },
				{ "&#8211;", "-" } };
		int i, j, k, l;

		i = s.indexOf("&", f);
		if (i > -1) {
			j = s.indexOf(";", i);
			f = i + 1;
			// --------
			if (j > i) {
				String temp = s.substring(i, j + 1);
				k = 0;
				while (k < escape.length) {
					if (escape[k][0].equals(temp)) {
						break;
					} else {
						k++;
					}
				}
				if (k < escape.length) {
					s = s.substring(0, i) + escape[k][1] + s.substring(j + 1);
					return unescapeHTML(s, f);
				}
				/*
				 * else if (temp.matches("&#\\d\\d\\d\\d;")) {
				 * s=s.substring(0,i) +
				 * 
				 * }
				 */
			}
		}
		return s;
	}

	/**
	 * Mapa ma klucze all - wszystkie dane zawarte runtime - czas trwania rating
	 * - ocena (Redakcji albo IMDB country - kraj produkcji release - premiera
	 * genre - gatunek description - opis filmu
	 * 
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public Map<String, String> parseFilmDetails(String url) throws IOException {
		final String HTML_START = "<div id=\"wpCenter\">";
		final String HTML_END = "<div id=\"wpRight\">";
		final String DESC_START = "<div class=\"kat\">";
		final String DESC_END = "<div class=\"clr\"";

		Map<String, String> details = new HashMap<String, String>();
		details.put("all", "");
		details.put("runtime", "");
		details.put("rating", "");
		details.put("country", "");
		details.put("release", "");
		details.put("genre", "");
		details.put("description", "");

		try {
			// String html = readFileAsString(url);
			String html = new URLLoader().urlGet(url);

			// Znajdujemy koniec i początek
			int htmlStart = html.indexOf(HTML_START);
			int htmlEnd = html.indexOf(HTML_END);
			if (htmlStart == -1 || htmlEnd == -1) {
				//System.out.println("htmlStart:" + htmlStart + " htmlEnd:" + htmlEnd);
				return details;
			}
			html = html.substring(htmlStart, htmlEnd);
			// System.out.println(html);

			// Znajdujemy opis
			int descStart = html.indexOf(DESC_START);
			int descEnd = html.indexOf(DESC_END);
			if (descStart == -1 || descEnd == -1) {
				//System.out.println("descStart:" + descStart + " descEnd:" + descEnd);
				details.put("description", "Nie udało się pobrać opisu " + "descStart:" + descStart + " descEnd:" + descEnd);
			}
			String description = html.substring(descStart, descEnd);
			description = description.substring(description.indexOf("<img"));
			description = description.substring(description.indexOf("/>") + 2);
			description = description.replaceAll("\n", "");
			description = description.replaceAll("\r", "");
			description = description.replaceAll("<br/>", "\n");
			description = description.replaceAll("<br />", "\n");
			description = description.replaceAll("\n\n", "\n");
			description = unescapeHTML(description, 0).trim();
			//System.out.println(description);
			details.put("description", description);
			html = html.substring(descEnd);

			while (html.indexOf("<b>") > -1) {
				int bStart = html.indexOf("<b>");
				boolean findNextB = false;
				int nextB = 0;
				int nextBa = bStart + 3;
				while (!findNextB) {
					nextB = html.indexOf("<b>", nextBa);
					if (nextB == -1) {
						nextB = html.indexOf("<div class=\"clr\"", nextBa);
						if (nextB == -1) {
							nextB = html.length() - 1;
							findNextB = true;
						}
					}
					nextBa = html.indexOf("<b><a", nextBa);
					if (nextBa == nextB) {
						nextBa++;
					} else {
						findNextB = true;
					}

				}
				// Szukamy końca bStart
				int bEnd = html.indexOf("</b>");
				String key = html.substring(bStart + 3, bEnd).trim();
				//System.out.print(key);
				String value = html.substring(bEnd, nextB);
				if ("Gatunek:".equals(key)) {
					value = value.replaceAll("<br>", " ");
					value = value.replaceAll("<br/>", " ");
					value = value.replaceAll("<br />", " ");
				}
				value = unescapeHTML(value.replaceAll("\\<.*?\\>", ""), 0).trim();
				//System.out.println(value);
				insertToMap(key, value, details);
				html = html.substring(nextB);
				details.put("all", details.get("all") + key + " " + value + "\n");
			}
		} catch (Exception e) {
			details.put("all", details.get("all") + e.getMessage() + "\n");
		}
		return details;
	}

	private void insertToMap(String key, String value, Map<String, String> details) {
		if ("Premiera kinowa:".equals(key)) {
			details.put("release", value);
		} else if ("Gatunek:".equals(key)) {
			details.put("genre", value);
		} else if ("Kraj produkcji:".equals(key)) {
			details.put("country", value);
		} else if ("Czas trwania:".equals(key)) {
			details.put("runtime", value);
		} else if ("Ocena redakcji:".equals(key)) {
			details.put("rating", value);
		} else if ("Ocena IMDB:".equals(key)) {
			details.put("rating", value);
		}

	}

	public static void main(String... args) {
		RSSParser rss = new RSSParser();
		List<FilmBean> films = rss.parse();
	}
}
